#include <iostream>
#include <mutex>
#include <thread>


using namespace std;


/*使用lock_guard或者unique_lock能避免忘记解锁这种问题。
lock_guard():
其原理是：声明一个局部的lock_guard对象，在其构造函数中进行加锁，
在其析构函数中进行解锁。最终的结果就是：创建即加锁，作用域结束自动解锁。
从而使用lock_guard()就可以替代lock()与unlock()。
通过设定作用域，使得lock_guard在合适的地方被析构
（在互斥量锁定到互斥量解锁之间的代码叫做临界区（需要互斥访问共享资源的那段代码称为临界区），临界区范围应该尽可能的小，即lock互斥量后应该尽早unlock），
通过使用{}来调整作用域范围，可使得互斥量m在合适的地方被解锁：
*/

//全局的锁，控制线程，逻辑不会互相混着打印处理，当一个线程获取了锁，另外一个地的获取同样的锁的地方就会等你上次锁释放了才会执行
mutex m;
void fun1(int a )
{
    lock_guard<mutex> g1(m);
    cout << "fun1 正在执行 "<<endl;
    cout << "原始a "<<a<<endl;
    a=2;
    cout << "现在a为 "<<a<<endl;
}

void fun2(int a)
{
    {
        lock_guard<mutex> g2(m);
        cout << "fun2 正在执行 "<<endl;
        cout << "原始a "<<a<<endl;
        a=3;
        cout << "现在a为 "<<a<<endl;
    }
    cout<<"作用域外的"<<endl;

}

int main()
{
    int a=0;
    thread th1(fun1,a);
    thread th2(fun2,a);
//    th1.join();
//    th2.join();

    //如果没有阻塞等待，将会出现异常，主程序结束，子线程在运行的异常，所以一定要join或者死循环等待子线程执行完毕，才能结束主线成
    while (1) {
       this_thread::sleep_for(chrono::seconds(1));
    }
    return 0;
}
